package come.example.domain.strategy.service.rule.tree.factory.engine.impl;

import come.example.domain.strategy.model.vo.RuleLogicCheckTypeVO;
import come.example.domain.strategy.model.vo.RuleTreeNodeLineVO;
import come.example.domain.strategy.model.vo.RuleTreeNodeVO;
import come.example.domain.strategy.model.vo.RuleTreeVO;
import come.example.domain.strategy.service.rule.tree.ILogicTreeNode;
import come.example.domain.strategy.service.rule.tree.factory.DefaultTreeFactory;
import come.example.domain.strategy.service.rule.tree.factory.engine.IDecisionTreeEngine;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;

/**
 * 决策树引擎
 */

@Slf4j
public class DecisionTreeEngine implements IDecisionTreeEngine {

    private final Map<String, ILogicTreeNode> logicTreeNodeGroup;

    private final RuleTreeVO ruleTreeVO;

    public DecisionTreeEngine(Map<String, ILogicTreeNode> logicTreeNodeGroup, RuleTreeVO ruleTreeVO) {
        this.logicTreeNodeGroup = logicTreeNodeGroup;
        this.ruleTreeVO = ruleTreeVO;
    }


    @Override
    public DefaultTreeFactory.StrategyAwardVO process(String userId, Long strategyId, Integer awardId) {
        DefaultTreeFactory.StrategyAwardVO strategyAwardVO = null;

        // 获取基础信息
        String nextNode = ruleTreeVO.getTreeRootRuleNode();// 拿到跟节点
        Map<String, RuleTreeNodeVO> treeNodeMap = ruleTreeVO.getTreeNodeMap();

        // 获取起始节点信息
        RuleTreeNodeVO ruleTreeNode = treeNodeMap.get(nextNode);

        while(null != nextNode)
        {
            // 获取决策节点
            // 根据节点名（如 "rule_lock"）获取节点配置——奖品规则（比如兜底奖品随机积分，完成n次后抽奖）
            ILogicTreeNode logicTreeNode = logicTreeNodeGroup.get(ruleTreeNode.getRuleKey());
            String ruleValue = ruleTreeNode.getRuleValue();
            // 决策节点计算
            DefaultTreeFactory.TreeActionEntity logicEntity = logicTreeNode.logic(userId, strategyId, awardId, ruleValue);
            // 是放行还是接管
            RuleLogicCheckTypeVO ruleLogicCheckTypeVO = logicEntity.getRuleLogicCheckType();
            // 拿到策略-奖品实体
            strategyAwardVO = logicEntity.getStrategyAwardVO();
            log.info("决策树引擎【{}】 treeId:{} node:{} code:{}", ruleTreeVO.getTreeName(), ruleTreeVO.getTreeId(), nextNode, ruleLogicCheckTypeVO.getCode());

            // 过滤操作
            nextNode = nextNode(ruleLogicCheckTypeVO.getCode(), ruleTreeNode.getTreeNodeLineVOList());
            ruleTreeNode = treeNodeMap.get(nextNode);

        }

        //返回最终结果
        return strategyAwardVO;
    }

    // node节点过滤
    private  String nextNode(String matterValue, List<RuleTreeNodeLineVO> ruleTreeNodeLineVOList) {
        if(null == ruleTreeNodeLineVOList || ruleTreeNodeLineVOList.isEmpty()) return null;
        for(RuleTreeNodeLineVO nodeLine: ruleTreeNodeLineVOList) {
            if(decisionLogic(matterValue, nodeLine)){
                return nodeLine.getRuleNodeTo(); // 返回下一个节点是啥
            }
        }

        //throw new RuntimeException("决策树引擎，nextNode计算失败（配置错误），未找到可执行节点！");
        // 走兜底奖品的话应该是没有这个东西的，就是返回null
        return null;
    }

    public boolean decisionLogic(String matterValue, RuleTreeNodeLineVO nodeLine){
        switch(nodeLine.getRuleLimitType()) {
            case EQUAL:
                return matterValue.equals(nodeLine.getRuleLimitValue().getCode());

            // 以下规则暂时不需要实现
            case GT:
            case LT:
            case GE:
            case LE:
            default:
                return false;
        }
    }
}
